package com.laundry.user.data.repository

import com.laundry.user.data.local.ServiceDao
import com.laundry.user.data.model.*
import com.laundry.user.network.ApiService
import com.laundry.user.network.ApiResponse
import com.laundry.user.network.PageResponse
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.catch
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class ServiceRepository @Inject constructor(
    private val apiService: ApiService,
    private val serviceDao: ServiceDao
) {
    
    /**
     * 获取服务列表（支持分页和筛选）
     */
    fun getServices(
        page: Int = 0,
        size: Int = 20,
        category: String? = null,
        lat: Double? = null,
        lng: Double? = null,
        radius: Int? = null,
        minPrice: Double? = null,
        maxPrice: Double? = null,
        rating: Double? = null,
        promoted: Boolean? = null,
        sort: String = "relevance"
    ): Flow<Result<PageResponse<Service>>> = flow {
        try {
            // 先从本地缓存获取数据
            if (page == 0) {
                val cachedServices = serviceDao.getCachedServices(category, lat, lng)
                if (cachedServices.isNotEmpty()) {
                    emit(Result.success(PageResponse(
                        content = cachedServices,
                        page = 0,
                        size = cachedServices.size,
                        totalElements = cachedServices.size.toLong(),
                        totalPages = 1,
                        hasNext = false,
                        hasPrevious = false
                    )))
                }
            }
            
            // 从网络获取最新数据
            val response = apiService.getServices(
                page = page,
                size = size,
                category = category,
                lat = lat,
                lng = lng,
                radius = radius,
                minPrice = minPrice,
                maxPrice = maxPrice,
                rating = rating,
                promoted = promoted,
                sort = sort
            )
            
            if (response.isSuccessful) {
                val apiResponse = response.body()
                if (apiResponse?.code == 200 && apiResponse.data != null) {
                    // 缓存第一页数据
                    if (page == 0) {
                        serviceDao.cacheServices(apiResponse.data.content)
                    }
                    emit(Result.success(apiResponse.data))
                } else {
                    emit(Result.failure(Exception(apiResponse?.message ?: "获取服务列表失败")))
                }
            } else {
                emit(Result.failure(Exception("网络请求失败: ${response.code()}")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }.catch { e ->
        emit(Result.failure(e))
    }
    
    /**
     * 搜索服务
     */
    fun searchServices(
        keyword: String,
        page: Int = 0,
        size: Int = 20,
        lat: Double? = null,
        lng: Double? = null,
        sort: String = "relevance"
    ): Flow<Result<PageResponse<Service>>> = flow {
        try {
            val response = apiService.searchServices(
                keyword = keyword,
                page = page,
                size = size,
                lat = lat,
                lng = lng,
                sort = sort
            )
            
            if (response.isSuccessful) {
                val apiResponse = response.body()
                if (apiResponse?.code == 200 && apiResponse.data != null) {
                    emit(Result.success(apiResponse.data))
                } else {
                    emit(Result.failure(Exception(apiResponse?.message ?: "搜索失败")))
                }
            } else {
                emit(Result.failure(Exception("网络请求失败: ${response.code()}")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }.catch { e ->
        emit(Result.failure(e))
    }
    
    /**
     * 获取服务详情
     */
    fun getServiceDetails(serviceId: String): Flow<Result<ServiceDetail>> = flow {
        try {
            // 先从本地缓存获取
            val cachedService = serviceDao.getServiceDetail(serviceId)
            if (cachedService != null) {
                emit(Result.success(cachedService))
            }
            
            // 从网络获取最新数据
            val response = apiService.getServiceDetails(serviceId)
            
            if (response.isSuccessful) {
                val apiResponse = response.body()
                if (apiResponse?.code == 200 && apiResponse.data != null) {
                    // 缓存详情数据
                    serviceDao.cacheServiceDetail(apiResponse.data)
                    emit(Result.success(apiResponse.data))
                } else {
                    emit(Result.failure(Exception(apiResponse?.message ?: "获取服务详情失败")))
                }
            } else {
                emit(Result.failure(Exception("网络请求失败: ${response.code()}")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }.catch { e ->
        emit(Result.failure(e))
    }
    
    /**
     * 获取服务分类
     */
    fun getServiceCategories(): Flow<Result<List<ServiceCategory>>> = flow {
        try {
            // 先从本地缓存获取
            val cachedCategories = serviceDao.getCachedCategories()
            if (cachedCategories.isNotEmpty()) {
                emit(Result.success(cachedCategories))
            }
            
            // 从网络获取最新数据
            val response = apiService.getServiceCategories()
            
            if (response.isSuccessful) {
                val apiResponse = response.body()
                if (apiResponse?.code == 200 && apiResponse.data != null) {
                    // 缓存分类数据
                    serviceDao.cacheCategories(apiResponse.data)
                    emit(Result.success(apiResponse.data))
                } else {
                    emit(Result.failure(Exception(apiResponse?.message ?: "获取分类失败")))
                }
            } else {
                emit(Result.failure(Exception("网络请求失败: ${response.code()}")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }.catch { e ->
        emit(Result.failure(e))
    }
    
    /**
     * 获取推荐服务
     */
    fun getRecommendedServices(
        lat: Double? = null,
        lng: Double? = null,
        limit: Int = 10
    ): Flow<Result<List<Service>>> = flow {
        try {
            val response = apiService.getServices(
                page = 0,
                size = limit,
                lat = lat,
                lng = lng,
                sort = "recommended"
            )
            
            if (response.isSuccessful) {
                val apiResponse = response.body()
                if (apiResponse?.code == 200 && apiResponse.data != null) {
                    emit(Result.success(apiResponse.data.content))
                } else {
                    emit(Result.failure(Exception(apiResponse?.message ?: "获取推荐服务失败")))
                }
            } else {
                emit(Result.failure(Exception("网络请求失败: ${response.code()}")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }.catch { e ->
        emit(Result.failure(e))
    }
    
    /**
     * 获取热门服务
     */
    fun getPopularServices(
        category: String? = null,
        limit: Int = 10
    ): Flow<Result<List<Service>>> = flow {
        try {
            val response = apiService.getServices(
                page = 0,
                size = limit,
                category = category,
                sort = "popular"
            )
            
            if (response.isSuccessful) {
                val apiResponse = response.body()
                if (apiResponse?.code == 200 && apiResponse.data != null) {
                    emit(Result.success(apiResponse.data.content))
                } else {
                    emit(Result.failure(Exception(apiResponse?.message ?: "获取热门服务失败")))
                }
            } else {
                emit(Result.failure(Exception("网络请求失败: ${response.code()}")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }.catch { e ->
        emit(Result.failure(e))
    }
    
    /**
     * 获取附近服务
     */
    fun getNearbyServices(
        lat: Double,
        lng: Double,
        radius: Int = 5000, // 5公里
        limit: Int = 20
    ): Flow<Result<List<Service>>> = flow {
        try {
            val response = apiService.getServices(
                page = 0,
                size = limit,
                lat = lat,
                lng = lng,
                radius = radius,
                sort = "distance"
            )
            
            if (response.isSuccessful) {
                val apiResponse = response.body()
                if (apiResponse?.code == 200 && apiResponse.data != null) {
                    emit(Result.success(apiResponse.data.content))
                } else {
                    emit(Result.failure(Exception(apiResponse?.message ?: "获取附近服务失败")))
                }
            } else {
                emit(Result.failure(Exception("网络请求失败: ${response.code()}")))
            }
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }.catch { e ->
        emit(Result.failure(e))
    }
    
    /**
     * 清除缓存
     */
    suspend fun clearCache() {
        serviceDao.clearCache()
    }
    
    /**
     * 刷新缓存
     */
    suspend fun refreshCache(
        category: String? = null,
        lat: Double? = null,
        lng: Double? = null
    ) {
        try {
            val response = apiService.getServices(
                page = 0,
                size = 50,
                category = category,
                lat = lat,
                lng = lng,
                sort = "relevance"
            )
            
            if (response.isSuccessful) {
                val apiResponse = response.body()
                if (apiResponse?.code == 200 && apiResponse.data != null) {
                    serviceDao.clearCache()
                    serviceDao.cacheServices(apiResponse.data.content)
                }
            }
        } catch (e: Exception) {
            // 忽略刷新缓存的错误
        }
    }
}

// 本地数据访问对象接口
interface ServiceDao {
    suspend fun getCachedServices(category: String?, lat: Double?, lng: Double?): List<Service>
    suspend fun cacheServices(services: List<Service>)
    suspend fun getServiceDetail(serviceId: String): ServiceDetail?
    suspend fun cacheServiceDetail(serviceDetail: ServiceDetail)
    suspend fun getCachedCategories(): List<ServiceCategory>
    suspend fun cacheCategories(categories: List<ServiceCategory>)
    suspend fun clearCache()
}
